﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;
using Constructor.Frames;
namespace Constructor
{
    public class Procedure
    {
        private MethodInfo _method;
        public Production Production { get; set; }
        public MethodInfo Method
        {
            get { return _method; }
            set
            {
                if (_method != value)
                {
                    _method = value;
                    Params = new List<NewItem>();
                    int cnt = _method.GetParameters().Count();
                    for (int i = 0; i < cnt; i++)
                        Params.Add(new NewItem(null));
                }
            }
        }
        public List<NewItem> Params { get; set; }
        public Procedure(Production p)
        {
            Production = p;
        }
        public void Load(DataSet ds)
        {
            DataTable dt = ds.Tables["Procedures"];
            DataTable dtParam = ds.Tables["Params"];
            if (dt != null)
            {
                DataRow row = dt.Select("owner_frame = '" + Production.OwnerSlot.Frame.Name + "'").First(o => o["owner_slot"].ToString() == Production.OwnerSlot.Name);
                if (row != null)
                {
                    Method = FunctionControler.GetMethod(row["method"].ToString());
                    int cnt = Method.GetParameters().Length;
                    if (dtParam != null)
                    {
                        DataRow[] rows = dtParam.Select("owner_frame = '" + Production.OwnerSlot.Frame.Name + "'").Where(o => o["owner_slot"].ToString() == Production.OwnerSlot.Name).ToArray();
                        if (rows.Length == cnt)
                        {
                            foreach (DataRow dr in rows)
                            {
                                ParameterInfo p = Method.GetParameters().First(o => o.Name == dr["name"].ToString());
                                Params[p.Position] = External.GetItem(dr["value"].ToString());
                            }
                        }
                    }
                }
            }
        }
        public string Text
        {
            get
            {
                if (Method != null)
                {
                    string result = Production.Procedure.Method.Name + "(";
                    foreach (NewItem item in Production.Procedure.Params)
                        result += item.Text + ",";
                    result = result.TrimEnd(',') + ")";
                    return result;
                }
                return "";
            }
        }
        public void SaveInDataSet(DataSet ds)
        {
            if (Method == null) return;
            DataTable dt = ds.Tables["Procedures"];
            DataTable dtParam = ds.Tables["Params"];
            DataRow dr = dt.NewRow();
            dr["owner_slot"] = Production.OwnerSlot.Name;
            dr["owner_frame"] = Production.OwnerSlot.Frame.Name;
            dr["method"] = Method.Name;
            foreach (NewItem param in Params)
            {
                DataRow drParam = dtParam.NewRow();
                drParam["owner_slot"] = Production.OwnerSlot.Name;
                drParam["owner_frame"] = Production.OwnerSlot.Frame.Name;
                drParam["name"] = Method.GetParameters()[Params.IndexOf(param)].Name;
                drParam["value"] = param.Text;
                dtParam.Rows.Add(drParam);
            }
            dt.Rows.Add(dr);
        }
        public Procedure Clone(Production pr)
        {
            Procedure p = new Procedure(pr);
            if (Method != null)
            {
                p.Method = FunctionControler.GetMethod(Method.Name);               
                foreach (NewItem item in Params)
                    p.Params[Params.IndexOf(item)] = item.Clone();
            }
            return p;
        }
    }
}
